﻿using Sustainalytics.Claims;
using Sustainalytics.ScreeningTool.BL;
using Sustainalytics.ScreeningTool.BL.Exceptions;
using Sustainalytics.ScreeningTool.Service.Utility;
using Sustainalytics.Utils.Serilog;
using System;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Cors;
using WebApi.OutputCache.V2;

namespace Sustainalytics.ScreeningTool.Service
{
    [EnableCors(origins: "*", headers: "*", methods: "*")]
    [RoutePrefix("api/v1/runs")]
    public class RunsController : ApiController, IRunsController
    {
        private readonly ICompanyScreening _companyScreening;

        private readonly IClaimsChecker _claimsChecker;

        public RunsController(
            IClaimsChecker claimsChecker,
            ICompanyScreening companyScreening)
        {
            try
            {
                CommonEventSerilog.Log.InitController();


                _claimsChecker = claimsChecker;
                _companyScreening = companyScreening;

                CommonEventSerilog.Log.InitControllerSuccess();
            }
            catch (Exception ex)
            {
                CommonEventSerilog.Log.InitControllerError(ex);
                throw new HttpResponseException(HttpStatusCode.InternalServerError);
            }
        }

        [Route("{id}")]
        public HttpResponseMessage Put([FromUri]Guid id, [FromBody] RunDto runDto)
        {
            var cache = Configuration.CacheOutputConfiguration().GetCacheOutputProvider(Request);
            cache.RemoveStartsWith(Configuration.CacheOutputConfiguration().MakeBaseCachekey("RunResults", "Get"));

            if (runDto == null || runDto.FilterId == Guid.Empty)
            {
                return Request.CreateResponse(
                    HttpStatusCode.BadRequest, new
                    {
                        ErrorStatusCode = ScreeningToolErrorCodesEnum.CreateRunInvalidFilter,
                        Message = "Cannot create a run for an empty filter."
                    });
            }

            var filterId = runDto.FilterId;
            var portfolioId = runDto.PortfolioId;

            try
            {
                if (!_claimsChecker.ValidateAnyShortName(this))
                    throw new AuthorizationException();

                _companyScreening.RunSelectedCriteriaOnScreeningData(filterId, portfolioId, runDto.Report, false, Guid.Empty, null);
            }
            catch (AuthorizationException ex)
            {
                return Request.CreateResponse(HttpStatusCode.Unauthorized);
            }
            catch (Exception ex)
            {
                return Request.CreateResponse(HttpStatusCode.InternalServerError, ex.Message);
            }

            return this.Request.CreateResponse(HttpStatusCode.OK, runDto);
        }

        [Route("{id}")]
        public HttpResponseMessage Delete(Guid id)
        {
            try
            {
                if (!_claimsChecker.ValidateAnyShortName(this))
                    throw new AuthorizationException();

                _companyScreening.ClearResultOutput(id);

                return Request.CreateResponse(HttpStatusCode.OK);
            }
            catch (AuthorizationException)
            {
                return Request.CreateResponse(HttpStatusCode.Unauthorized);
            }
            catch (Exception ex)
            {
                return Request.CreateResponse(HttpStatusCode.InternalServerError, ex.Message);
            }
        }
    }
}
